#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include "../include/test_framework.h"

// 测试结果统计
static int tests_run = 0;
static int tests_passed = 0;
static int tests_failed = 0;

// 测试宏
#define ASSERT_EQ(expected, actual) do { \
    tests_run++; \
    if ((expected) == (actual)) { \
        tests_passed++; \
        printf("✓ 测试通过: %s == %s\n", #expected, #actual); \
    } else { \
        tests_failed++; \
        printf("✗ 测试失败: %s != %s (期望: %d, 实际: %d)\n", \
               #expected, #actual, (int)(expected), (int)(actual)); \
    } \
} while(0)

#define ASSERT_NE(expected, actual) do { \
    tests_run++; \
    if ((expected) != (actual)) { \
        tests_passed++; \
        printf("✓ 测试通过: %s != %s\n", #expected, #actual); \
    } else { \
        tests_failed++; \
        printf("✗ 测试失败: %s == %s (不应该相等: %d)\n", \
               #expected, #actual, (int)(actual)); \
    } \
} while(0)

#define ASSERT_TRUE(condition) do { \
    tests_run++; \
    if (condition) { \
        tests_passed++; \
        printf("✓ 测试通过: %s 为真\n", #condition); \
    } else { \
        tests_failed++; \
        printf("✗ 测试失败: %s 为假\n", #condition); \
    } \
} while(0)

// 测试命令解析功能
void test_command_parsing() {
    printf("\n=== 测试命令解析功能 ===\n");
    
    // 测试有效命令
    ASSERT_EQ(CMD_PHOTO, parse_command_type("AT+AIGLASSPHOTO"));
    ASSERT_EQ(CMD_RECORD, parse_command_type("AT+AIGLASSRECORD"));
    ASSERT_EQ(CMD_RTSP, parse_command_type("AT+AIGLASSRTSP"));
    ASSERT_EQ(CMD_WIFI, parse_command_type("AT+AIGLASSWIFI"));
    ASSERT_EQ(CMD_OTA, parse_command_type("AT+AIGLASSOTA"));
    ASSERT_EQ(CMD_STATUS, parse_command_type("AT+STATUS"));
    ASSERT_EQ(CMD_HELP, parse_command_type("AT+HELP"));
    ASSERT_EQ(CMD_EXIT, parse_command_type("AT+EXIT"));
    
    // 测试大小写不敏感
    ASSERT_EQ(CMD_PHOTO, parse_command_type("at+aiglassphoto"));
    ASSERT_EQ(CMD_HELP, parse_command_type("at+help"));
    
    // 测试无效命令
    ASSERT_EQ(CMD_UNKNOWN, parse_command_type("INVALID_COMMAND"));
    ASSERT_EQ(CMD_UNKNOWN, parse_command_type(""));
    ASSERT_EQ(CMD_UNKNOWN, parse_command_type(NULL));
}

// 测试命令参数解析
void test_parameter_parsing() {
    printf("\n=== 测试命令参数解析 ===\n");
    
    test_command_t cmd;
    int result;
    
    // 测试无参数命令
    result = parse_command_parameters("AT+AIGLASSPHOTO\n", &cmd);
    ASSERT_EQ(0, result);
    ASSERT_EQ(CMD_PHOTO, cmd.type);
    ASSERT_EQ(0, strlen(cmd.parameters));
    
    // 测试带参数命令
    result = parse_command_parameters("AT+AIGLASSRECORD 10\n", &cmd);
    ASSERT_EQ(0, result);
    ASSERT_EQ(CMD_RECORD, cmd.type);
    ASSERT_TRUE(strcmp(cmd.parameters, "10") == 0);
    
    // 测试带多个参数
    result = parse_command_parameters("AT+AIGLASSWIFI MyWiFi\n", &cmd);
    ASSERT_EQ(0, result);
    ASSERT_EQ(CMD_WIFI, cmd.type);
    ASSERT_TRUE(strcmp(cmd.parameters, "MyWiFi") == 0);
    
    // 测试空输入
    result = parse_command_parameters("", &cmd);
    ASSERT_EQ(0, result);
    ASSERT_EQ(CMD_UNKNOWN, cmd.type);
}

// 测试命令队列功能
void test_command_queue() {
    printf("\n=== 测试命令队列功能 ===\n");
    
    cmd_queue_t queue;
    test_command_t cmd1, cmd2, cmd_out;
    
    // 初始化队列
    ASSERT_EQ(0, cmd_queue_init(&queue));
    ASSERT_TRUE(cmd_queue_is_empty(&queue));
    ASSERT_TRUE(!cmd_queue_is_full(&queue));
    
    // 准备测试命令
    memset(&cmd1, 0, sizeof(cmd1));
    cmd1.type = CMD_PHOTO;
    strcpy(cmd1.cmd_string, "AT+AIGLASSPHOTO");
    
    memset(&cmd2, 0, sizeof(cmd2));
    cmd2.type = CMD_RECORD;
    strcpy(cmd2.cmd_string, "AT+AIGLASSRECORD");
    
    // 测试入队操作
    ASSERT_EQ(0, cmd_queue_push(&queue, &cmd1));
    ASSERT_TRUE(!cmd_queue_is_empty(&queue));
    
    ASSERT_EQ(0, cmd_queue_push(&queue, &cmd2));
    
    // 测试出队操作
    ASSERT_EQ(0, cmd_queue_pop(&queue, &cmd_out));
    ASSERT_EQ(CMD_PHOTO, cmd_out.type);
    ASSERT_TRUE(strcmp(cmd_out.cmd_string, "AT+AIGLASSPHOTO") == 0);
    
    ASSERT_EQ(0, cmd_queue_pop(&queue, &cmd_out));
    ASSERT_EQ(CMD_RECORD, cmd_out.type);
    
    // 队列应该为空
    ASSERT_TRUE(cmd_queue_is_empty(&queue));
    
    // 清理队列
    cmd_queue_cleanup(&queue);
}

// 测试命令处理功能
void test_command_processing() {
    printf("\n=== 测试命令处理功能 ===\n");
    
    test_command_t cmd;
    test_result_t result;
    
    // 测试拍照命令
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_PHOTO;
    strcpy(cmd.cmd_string, "AT+AIGLASSPHOTO");
    result = handle_photo_command(&cmd);
    ASSERT_EQ(TEST_SUCCESS, result);
    
    // 测试录像命令
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_RECORD;
    strcpy(cmd.cmd_string, "AT+AIGLASSRECORD");
    strcpy(cmd.parameters, "5");
    result = handle_record_command(&cmd);
    ASSERT_EQ(TEST_SUCCESS, result);
    
    // 测试RTSP命令
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_RTSP;
    strcpy(cmd.cmd_string, "AT+AIGLASSRTSP");
    result = handle_rtsp_command(&cmd);
    ASSERT_EQ(TEST_SUCCESS, result);
    
    // 测试WiFi命令
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_WIFI;
    strcpy(cmd.cmd_string, "AT+AIGLASSWIFI");
    result = handle_wifi_command(&cmd);
    ASSERT_EQ(TEST_SUCCESS, result);
    
    // 测试OTA命令
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_OTA;
    strcpy(cmd.cmd_string, "AT+AIGLASSOTA");
    result = handle_ota_command(&cmd);
    ASSERT_EQ(TEST_SUCCESS, result);
    
    // 测试状态命令
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_STATUS;
    strcpy(cmd.cmd_string, "AT+STATUS");
    result = handle_status_command(&cmd);
    ASSERT_EQ(TEST_SUCCESS, result);
    
    // 测试帮助命令
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_HELP;
    strcpy(cmd.cmd_string, "AT+HELP");
    result = handle_help_command(&cmd);
    ASSERT_EQ(TEST_SUCCESS, result);
}

// 测试线程安全性
void test_thread_safety() {
    printf("\n=== 测试线程安全性 ===\n");
    
    // 初始化测试框架
    ASSERT_EQ(0, test_framework_init());
    
    // 测试框架状态
    ASSERT_EQ(THREAD_IDLE, g_test_framework.parser_status);
    ASSERT_EQ(THREAD_IDLE, g_test_framework.processor_status);
    ASSERT_EQ(THREAD_IDLE, g_test_framework.monitor_status);
    ASSERT_EQ(0, g_test_framework.running);
    ASSERT_EQ(1, g_test_framework.interactive_mode);
    
    // 测试队列并发访问
    cmd_queue_t *queue = &g_test_framework.cmd_queue;
    test_command_t cmd, cmd_out;
    
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_PHOTO;
    strcpy(cmd.cmd_string, "AT+AIGLASSPHOTO");
    
    // 多次并发操作测试
    for (int i = 0; i < 10; i++) {
        ASSERT_EQ(0, cmd_queue_push(queue, &cmd));
        ASSERT_EQ(0, cmd_queue_pop(queue, &cmd_out));
        ASSERT_EQ(CMD_PHOTO, cmd_out.type);
    }
    
    // 清理测试框架
    test_framework_cleanup();
}

// 工具函数测试
void test_utility_functions() {
    printf("\n=== 测试工具函数 ===\n");
    
    // 测试结果字符串转换
    ASSERT_TRUE(strcmp(get_result_string(TEST_SUCCESS), "SUCCESS") == 0);
    ASSERT_TRUE(strcmp(get_result_string(TEST_FAILURE), "FAILURE") == 0);
    ASSERT_TRUE(strcmp(get_result_string(TEST_TIMEOUT), "TIMEOUT") == 0);
    ASSERT_TRUE(strcmp(get_result_string(TEST_PARAM_ERROR), "PARAM_ERROR") == 0);
    ASSERT_TRUE(strcmp(get_result_string(TEST_BUSY), "BUSY") == 0);
    ASSERT_TRUE(strcmp(get_result_string(TEST_NOT_SUPPORTED), "NOT_SUPPORTED") == 0);
    
    // 测试线程状态字符串转换
    ASSERT_TRUE(strcmp(get_thread_status_string(THREAD_IDLE), "IDLE") == 0);
    ASSERT_TRUE(strcmp(get_thread_status_string(THREAD_RUNNING), "RUNNING") == 0);
    ASSERT_TRUE(strcmp(get_thread_status_string(THREAD_BUSY), "BUSY") == 0);
    ASSERT_TRUE(strcmp(get_thread_status_string(THREAD_ERROR), "ERROR") == 0);
    ASSERT_TRUE(strcmp(get_thread_status_string(THREAD_STOPPED), "STOPPED") == 0);
}

// 压力测试
void test_stress() {
    printf("\n=== 压力测试 ===\n");
    
    // 初始化测试框架
    ASSERT_EQ(0, test_framework_init());
    
    cmd_queue_t *queue = &g_test_framework.cmd_queue;
    test_command_t cmd, cmd_out;
    
    memset(&cmd, 0, sizeof(cmd));
    cmd.type = CMD_PHOTO;
    strcpy(cmd.cmd_string, "AT+AIGLASSPHOTO");
    
    printf("执行压力测试: 1000次命令队列操作...\n");
    
    // 大量命令处理测试
    for (int i = 0; i < 1000; i++) {
        if (cmd_queue_push(queue, &cmd) == 0) {
            if (cmd_queue_pop(queue, &cmd_out) == 0) {
                ASSERT_EQ(CMD_PHOTO, cmd_out.type);
            }
        }
        
        // 每100次显示进度
        if ((i + 1) % 100 == 0) {
            printf("已完成 %d/1000 次操作\n", i + 1);
        }
    }
    
    printf("✓ 压力测试完成\n");
    
    // 清理测试框架
    test_framework_cleanup();
}

// 运行所有测试
int main() {
    printf("========================================\n");
    printf("   AI Glass Linux 测试框架 - 单元测试\n");
    printf("========================================\n");
    
    // 运行各项测试
    test_command_parsing();
    test_parameter_parsing();
    test_command_queue();
    test_command_processing();
    test_thread_safety();
    test_utility_functions();
    test_stress();
    
    // 输出测试结果
    printf("\n========================================\n");
    printf("              测试结果统计\n");
    printf("========================================\n");
    printf("总测试数:   %d\n", tests_run);
    printf("通过测试:   %d\n", tests_passed);
    printf("失败测试:   %d\n", tests_failed);
    printf("成功率:     %.1f%%\n", tests_run > 0 ? (float)tests_passed * 100.0 / tests_run : 0.0);
    
    if (tests_failed == 0) {
        printf("\n🎉 所有测试通过！\n");
        return 0;
    } else {
        printf("\n❌ 有 %d 个测试失败\n", tests_failed);
        return 1;
    }
}